// Fill out your copyright notice in the Description page of Project Settings.


#include "RuntimeMeshActor.h"

ARuntimeMeshActor::ARuntimeMeshActor()
{
 	PrimaryActorTick.bCanEverTick = true;
	_angle = 0.0f; _playing = true;

	_mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("Mesh"));
	SetRootComponent(_mesh);

	static ConstructorHelpers::FObjectFinder<UMaterial> mtlAsset(
		TEXT("Material'/Game/StarterContent/Materials/M_ColorGrid_LowSpec.M_ColorGrid_LowSpec'"));
	if (mtlAsset.Succeeded())
	{
		UMaterialInstanceDynamic* mtl = UMaterialInstanceDynamic::Create(mtlAsset.Object, NULL);
		_mesh->SetMaterial(0, mtl);
	}
}

void ARuntimeMeshActor::BeginPlay()
{
	Super::BeginPlay();
	UpdateMesh(100.0f, 100.0f, true);

	InputComponent = NewObject<UInputComponent>(this);
	InputComponent->RegisterComponent();
	InputComponent->BindAction("Home", IE_Released, this, &ARuntimeMeshActor::PlayAnimation);
	EnableInput(GetWorld()->GetFirstPlayerController());
}

void ARuntimeMeshActor::UpdateMesh(float x, float y, bool firstCreated)
{
	TArray<FVector> vertices;
	vertices.Add(FVector(0.0, 0.0, 0.0));
	vertices.Add(FVector(x, 0.0, 0.0));
	vertices.Add(FVector(x, y, 0.0));
	vertices.Add(FVector(0.0, y, 0.0));
	vertices.Add(FVector(0.0, 0.0, 100.0));
	vertices.Add(FVector(x, 0.0, 100.0));
	vertices.Add(FVector(x, y, 100.0));
	vertices.Add(FVector(0.0, y, 100.0));

	TArray<FVector> normals;
	normals.Add(FVector(-1.0, -1.0, 0.0).GetUnsafeNormal());
	normals.Add(FVector(1.0, -1.0, 0.0).GetUnsafeNormal());
	normals.Add(FVector(1.0, 1.0, 0.0).GetUnsafeNormal());
	normals.Add(FVector(-1.0, 1.0, 0.0).GetUnsafeNormal());
	normals.Add(FVector(-1.0, -1.0, 1.0).GetUnsafeNormal());
	normals.Add(FVector(1.0, -1.0, 1.0).GetUnsafeNormal());
	normals.Add(FVector(1.0, 1.0, 1.0).GetUnsafeNormal());
	normals.Add(FVector(-1.0, 1.0, 1.0).GetUnsafeNormal());

	TArray<FVector2D> uv;
	uv.Add(FVector2D(0.0, 0.0)); uv.Add(FVector2D(0.25, 0.0));
	uv.Add(FVector2D(0.5, 0.0)); uv.Add(FVector2D(0.75, 0.0));
	uv.Add(FVector2D(0.0, 1.0)); uv.Add(FVector2D(0.25, 1.0));
	uv.Add(FVector2D(0.5, 1.0)); uv.Add(FVector2D(0.75, 1.0));

	TArray<FProcMeshTangent> emptyTangent;
	TArray<FLinearColor> emptyColor;
	if (firstCreated)
	{
		TArray<int32> indices;
		indices.Add(0); indices.Add(1); indices.Add(2);
		indices.Add(0); indices.Add(2); indices.Add(3);
		indices.Add(0); indices.Add(5); indices.Add(1);
		indices.Add(0); indices.Add(4); indices.Add(5);
		indices.Add(2); indices.Add(7); indices.Add(3);
		indices.Add(2); indices.Add(6); indices.Add(7);
		indices.Add(4); indices.Add(6); indices.Add(5);
		indices.Add(4); indices.Add(7); indices.Add(6);
		indices.Add(0); indices.Add(3); indices.Add(7);
		indices.Add(0); indices.Add(7); indices.Add(4);
		indices.Add(1); indices.Add(6); indices.Add(2);
		indices.Add(1); indices.Add(5); indices.Add(6);
		_mesh->CreateMeshSection_LinearColor(0, vertices, indices, normals, uv,
			                                 emptyColor, emptyTangent, true);
	}
	else
		_mesh->UpdateMeshSection_LinearColor(0, vertices, normals, uv,
			                                 emptyColor, emptyTangent);
}

void ARuntimeMeshActor::PlayAnimation()
{
	_playing = !_playing;
	UE_LOG(LogTemp, Warning, TEXT("Play or pause the animation"));
}

void ARuntimeMeshActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	UpdateMesh(100.0f * cos(_angle), 100.0f * cos(_angle), false);
	if (_playing) _angle += 0.02f;
}
